import axios from "axios";
import cheerio from "cheerio";
import { iArg } from "../iArg";
import { iFetcher } from "../iFetcher";
import { fetchRawData } from "./fetchRawData.js";

class UserRatingFetcher implements iFetcher {
  public data: UserRating = new UserRating();
  public async fetch(arg: iArg): Promise<string> {
    const { contestType="algo", userName } = arg;
    if (!userName){
      return ""
    }
    let htmlText=""
    htmlText=await fetchRawData(`https://atcoder.jp/users/${userName}?contestType=${contestType}&graph=rating`)
    if(htmlText===""){
      return ""
    }

    let $ = cheerio.load(htmlText);
    let historyText = $("script")
      .text()
      .match(new RegExp(`var rating_history=.*]`, "g"));
    if (historyText == null) {
      throw new Error("wrong cannot find match data!");
    }
    this.data.history = JSON.parse(historyText[0].slice(19));

    let ele = $(".mt-2").find("tr").find("td");
    this.data.rank = ele.eq(0).text();
    this.data.currentRating = Number(ele.eq(1).find("span").eq(0).text());
    this.data.highestRating = Number(ele.eq(2).find("span").eq(0).text());
    this.data.rateMatches = ele.eq(3).text();
    this.data.lastComputed = ele.eq(4).text();
  
    htmlText=await fetchRawData(`https://atcoder.jp/users/${userName}?contestType=${contestType}&graph=dist`)
    if(htmlText===""){
      return JSON.stringify(this.data);
    }
  
    $ = cheerio.load(htmlText);
    let dataText = $("script")
      .eq(12)
      .text()
      .match(/\[.*\]/g);
    if (dataText == null) {
      throw new Error("parse error!!");
    }
    this.data.ratingDistibution = new Distibution(
      JSON.parse(dataText[0]),
      JSON.parse(dataText[1]),
      this.data.currentRating
    );
    for (let item of this.data.history) {
      item.EndTime=item.EndTime*1000
      item.StandingsUrl = "https://atcoder.jp" + item.StandingsUrl;
    }

    return JSON.stringify(this.data);
  }
}
class UserRating {
  constructor(
    currentRating: number = 0,
    highestRating: number = 0,
    history: ratingInfo[] = [],
    rank: string = "",
    rateMatches: string = "",
    lastComputed: string = "",
    ratingdistibution: Distibution = new Distibution()
  ) {
    this.currentRating = currentRating;
    this.highestRating = highestRating;
    this.history = history;
    this.rank = rank;
    this.rateMatches = rateMatches;
    this.lastComputed = lastComputed;
    this.ratingDistibution = ratingdistibution;
  }
  rank: string;
  currentRating: number;
  highestRating: number;
  rateMatches: string;
  lastComputed: string;
  history: ratingInfo[];
  ratingDistibution: Distibution;
}

//rating 记录
interface ratingInfo {
  EndTime: number;
  NewRating: number;
  OldRating: number;
  Place: number;
  ContestName: string;
  StandingsUrl: string;
}
class Distibution {
  constructor(xaxis: number[] = [], data: number[] = [], now: number = -1) {
    this.xaxis = xaxis;
    this.data = data;
    this.now = now;
  }
  xaxis: number[];
  data: number[];
  now: number;
}



export { UserRatingFetcher};
